//******************************************************************************
/**
 *
 * @file	fldeff_flash
 * @brief	フィールド技・フラッシュ
 * @author	saito
 * @data	07.12.19
 *
 */
//******************************************************************************
#include "common.h"
#include "fieldsys.h"
#include "field_effect.h"
#include "fieldobj.h"

//==============================================================================
//	define
//==============================================================================

//==============================================================================
//	typedef struct
//==============================================================================
//--------------------------------------------------------------
///	FE_FLASH型
//--------------------------------------------------------------
typedef struct _TAG_FE_FLASH * FE_FLASH_PTR;

//--------------------------------------------------------------
///	FE_FLASH構造体
//--------------------------------------------------------------
typedef struct _TAG_FE_FLASH
{
	FE_SYS *fes;
	NNSG3dRenderObj Render;
	NNSG3dResMdl *Model;
	NNSG3dResFileHeader *ResFile;
	EOA_PTR EoaPtr;
	float Scale;
}FE_FLASH;

#define FE_FLASH_SIZE (sizeof(FE_FLASH)) ///<FE_FLASHサイズ

//--------------------------------------------------------------
///	FLASH_ADD_H構造体
//--------------------------------------------------------------
typedef struct
{
	FE_SYS *fes;							///<FE_SYS *
	FE_FLASH_PTR Flash;						///<FE_FLASH_PTR
	FIELD_OBJ_PTR FldObj;					///<対象FIELD_OiBJ_PTR
	int Len;
	VecFx32 DirVec;
}FLASH_ADD_H;

#define FLASH_ADD_H_SIZE (sizeof(FLASH_ADD_H)) ///<FLASH_ADD_Hサイズ

//--------------------------------------------------------------
///	FLASH_WORK構造体
//--------------------------------------------------------------
typedef struct
{
///	int obj_code;								///<影対象OBJコード
///	int obj_id;									///<影対象OBJID
///	int zone_id;								///<影対象ゾーンID
///	int vanish_sw;								///<非表示SW
	int Use;
	FLASH_ADD_H Head;							///<追加時のFLASH_ADD_H
}FLASH_WORK;

#define FLASH_WORK_SIZE (sizeof(FLASH_WORK))	///<FLASH_WORKサイズ

//==============================================================================
//	プロトタイプ
//==============================================================================
static void Flash_GraphicInit( FE_FLASH_PTR sd );
static void Flash_GraphicDelete( FE_FLASH_PTR sd );

static const EOA_H_NPP DATA_EoaH_Flash;

//==============================================================================
//	システム
//==============================================================================
//--------------------------------------------------------------
/**
 * フラッシュ初期化
 * @param	fes		FE_SYS *
 * @retval	void*	エフェクト使用ワーク
 */
//--------------------------------------------------------------
void * FE_Flash_Init( FE_SYS *fes )
{
	FE_FLASH_PTR fl;

	fl = FE_AllocClearMemory( fes, FE_FLASH_SIZE, ALLOC_FR, 0 );
	fl->fes = fes;
	fl->EoaPtr = NULL;
	fl->Scale = 1.0;

	Flash_GraphicInit( fl );

	return( fl );
}

//--------------------------------------------------------------
/**
 * フラッシュ削除
 * @param	work	エフェクト使用ワーク
 * @retval	nothing
 */
//--------------------------------------------------------------
void FE_Flash_Delete( void *work )
{
	FE_FLASH_PTR fl = work;
	Flash_GraphicDelete( fl );
	FE_FreeMemory( fl );
}

//--------------------------------------------------------------
/**
 * フラッシュ グラフィック初期化
 * @param	fl_ptr	FE_FLASH_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
static void Flash_GraphicInit( FE_FLASH_PTR fl_ptr )
{
	NNSG3dResMdl *res_model;

	FE_simple3DModelInit( fl_ptr->fes, NARC_fldeff_dun_spot_nsbmd, ALLOC_FR,
			&fl_ptr->Render, &fl_ptr->Model, &fl_ptr->ResFile );
}

//--------------------------------------------------------------
/**
 * フラッシュグラフィック削除
 * @param	fl_ptr	FE_FLASH_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
static void Flash_GraphicDelete( FE_FLASH_PTR fl_ptr )
{
	FE_FreeMemory( fl_ptr->ResFile );
}

//==============================================================================
//	フラッシュEOA
//==============================================================================
//--------------------------------------------------------------
/**
 * フラッシュ追加
 * @param	fldobj		FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
EOA_PTR FE_FldOBJFlash_Add( FIELD_OBJ_PTR fldobj )
{
	int param,pri;
	FLASH_ADD_H head;
	FE_SYS *fes;
	VecFx32 mtx;
	FIELDSYS_WORK *fsys;

	fes = FE_FieldOBJ_FE_SYS_Get( fldobj );
	fsys = FE_FieldSysWorkGet( fes );

	head.fes = fes;
	head.Flash = FE_EffectWorkGet( fes, FE_FLD_FLASH );

	if (head.Flash->EoaPtr != NULL){
		OS_Printf("既にあるので、作成はせず、に既存ポインタを返します\n");
		return head.Flash->EoaPtr;
	}

	head.FldObj = fldobj;
	//方向ベクトル算出
	{
		VecFx32 obj_vec,cam_vec;
		//座標取得
		FieldOBJ_VecPosGet( fldobj, &obj_vec );
		//カメラ座標取得
		cam_vec = GFC_GetCameraPos(fsys->camera_ptr);
		//方向ベクトル作成
		VEC_Subtract( &cam_vec, &obj_vec, &head.DirVec );
		//距離算出
		head.Len = VEC_Distance(&cam_vec, &obj_vec);
		//距離決定
		head.Len = head.Len/3;
		//方向ベクトルを正規化
		VEC_Normalize(&head.DirVec, &head.DirVec);
	}

	FieldOBJ_VecPosGet( fldobj, &mtx );

	param = FLASH_NONE_USE;

	pri = FieldOBJ_TCBPriGet( fldobj, FLDOBJ_TCBPRI_OFFS_AFTER );
	head.Flash->EoaPtr = FE_EoaAddNpp( fes, &DATA_EoaH_Flash, &mtx, param, &head, pri );

	return head.Flash->EoaPtr;
}

//--------------------------------------------------------------
/**
 * フラッシュスケールセット
 * @param	ptr			eoaポインタ
 * @param	inScale		スケール
 * @retval	nothing
 */
//--------------------------------------------------------------
void FE_FldOBJFlash_SetScale(EOA_PTR ptr, const float inScale)
{
	FLASH_WORK *work;
	work = EOA_LocalWorkGet( ptr );
	work->Head.Flash->Scale = inScale;
}

//--------------------------------------------------------------
/**
 * EOA フラッシュ　初期化
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	int		TRUE=正常終了。FALSE=異常終了
 */
//--------------------------------------------------------------
static int EoaFlash_Init( EOA_PTR eoa, void *wk )
{
	FLASH_WORK *work;
	const FLASH_ADD_H *head;

	work = wk;
	head = EOA_AddPtrGet( eoa );
	work->Head = *head;

	work->Use = EOA_AddParamGet( eoa );
/**
	work->obj_code = FieldOBJ_OBJCodeGet( work->Head.FldObj );
	work->obj_id = FieldOBJ_OBJIDGet( work->Head.FldObj );

	if( FieldOBJ_StatusBitCheck_Alies(work->head.fldobj) == TRUE ){
		work->zone_id = FieldOBJ_ZoneIDGetAlies( work->head.fldobj );
	}else{
		work->zone_id = FieldOBJ_ZoneIDGet( work->head.fldobj );
	}
*/
	return( TRUE );
}

//--------------------------------------------------------------
/**
 * EOA フラッシュ　削除
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFlash_Delete( EOA_PTR eoa, void *wk )
{
}

//--------------------------------------------------------------
/**
 * EOA フラッシュ　動作
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFlash_Move( EOA_PTR eoa, void *wk )
{
	FLASH_WORK *work;
	FIELD_OBJ_PTR fldobj;

	work = wk;
	fldobj = work->Head.FldObj;
/**
	if( FieldOBJ_CheckSameIDOBJCodeIn(
		fldobj,work->obj_code,work->obj_id,work->zone_id) == FALSE ){
		FE_EoaDelete( eoa );										//同一ではない
		return;
	}

	if( FieldOBJ_FieldOBJSysStatusBitCheck(fldobj,FLDOBJSYS_STA_BIT_SHADOW_JOIN_NOT) ){
		FE_EoaDelete( eoa );
		return;
	}

	work->vanish_sw = FALSE;

	if( FieldOBJ_StatusBit_CheckEasy(fldobj,
		FLDOBJ_STA_BIT_VANISH|FLDOBJ_STA_BIT_SHADOW_VANISH) == TRUE ){
		work->vanish_sw = TRUE;									//非表示
		return;
	}
*/
	{
		VecFx32 obj_vec, dst;
		FieldOBJ_VecPosGet( fldobj, &obj_vec );
		//フラッシュOBJ位置決定
		VEC_MultAdd(work->Head.Len, &work->Head.DirVec, &obj_vec, &dst);


		EOA_MatrixSet( eoa, &dst );
	}
}

//--------------------------------------------------------------
/**
 * EOA フラッシュ　描画
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFlash_Draw( EOA_PTR eoa, void *wk )
{
	FLASH_WORK *work;

	work = wk;
/**
	if( work->vanish_sw == TRUE ){
		return;
	}
*/
	{
		VecFx32 vec;
		VecFx32 scale;
		MtxFx33 rot = { FX32_ONE, 0,0,0, FX32_ONE, 0,0,0,FX32_ONE};

		scale.x = FX32_ONE * work->Head.Flash->Scale;
		scale.y = FX32_ONE * work->Head.Flash->Scale;
		scale.z = FX32_ONE * work->Head.Flash->Scale;

		EOA_MatrixGet( eoa, &vec );

		simple_3DModelDraw( &work->Head.Flash->Render, &vec, &rot, &scale );
	}
}

///	フラッシュEOA_H
//--------------------------------------------------------------
static const EOA_H_NPP DATA_EoaH_Flash =
{
	FLASH_WORK_SIZE,
	EoaFlash_Init,
	EoaFlash_Delete,
	EoaFlash_Move,
	EoaFlash_Draw,
};